home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / HTTP_DATE.PY < prev    next >
Encoding:
Text File  |  2000-11-10  |  3.4 KB  |  132 lines

  1. # -*- Mode: Python; tab-width: 4 -*-
  2.  
  3. import regex
  4. import string
  5. import time
  6.  
  7. def concat (*args):
  8.     return string.joinfields (args, '')
  9.  
  10. def join (seq, field=' '):
  11.     return string.joinfields (seq, field)
  12.  
  13. def group (s):
  14.     return '\\(' + s + '\\)'
  15.  
  16. short_days = ['sun','mon','tue','wed','thu','fri','sat']
  17. long_days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
  18.  
  19. short_day_reg = group (join (short_days, '\\|'))
  20. long_day_reg = group (join (long_days, '\\|'))
  21.  
  22. daymap = {}
  23. for i in range(7):
  24.     daymap[short_days[i]] = i
  25.     daymap[long_days[i]] = i
  26.  
  27. hms_reg = join (3 * [group('[0-9][0-9]')], ':')
  28.  
  29. months = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']
  30.  
  31. monmap = {}
  32. for i in range(12):
  33.     monmap[months[i]] = i+1
  34.  
  35. months_reg = group (join (months, '\\|'))
  36.  
  37. # From draft-ietf-http-v11-spec-07.txt/3.3.1
  38. #       Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
  39. #       Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
  40. #       Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
  41.  
  42. # rfc822 format
  43. rfc822_date = join (
  44.     [concat (short_day_reg,','),    # day
  45.      group('[0-9][0-9]?'),          # date
  46.      months_reg,                    # month
  47.      group('[0-9]+'),               # year
  48.      hms_reg,                       # hour minute second
  49.      'gmt'
  50.      ],
  51.     ' '
  52.     )
  53.  
  54. rfc822_reg = regex.compile (rfc822_date)
  55.  
  56. def unpack_rfc822 ():
  57.     g = rfc822_reg.group
  58.     a = string.atoi
  59.     return (
  60.         a(g(4)),        # year
  61.         monmap[g(3)],   # month
  62.         a(g(2)),        # day
  63.         a(g(5)),        # hour
  64.         a(g(6)),        # minute
  65.         a(g(7)),        # second
  66.         0,
  67.         0,
  68.         0
  69.         )
  70.  
  71. # rfc850 format
  72. rfc850_date = join (
  73.     [concat (long_day_reg,','),
  74.      join (
  75.          [group ('[0-9][0-9]?'),
  76.           months_reg,
  77.           group ('[0-9]+')
  78.           ],
  79.          '-'
  80.          ),
  81.      hms_reg,
  82.      'gmt'
  83.      ],
  84.     ' '
  85.     )
  86.  
  87. rfc850_reg = regex.compile (rfc850_date)
  88. # they actually unpack the same way
  89. def unpack_rfc850 ():
  90.     g = rfc850_reg.group
  91.     a = string.atoi
  92.     return (
  93.         a(g(4)),        # year
  94.         monmap[g(3)],   # month
  95.         a(g(2)),        # day
  96.         a(g(5)),        # hour
  97.         a(g(6)),        # minute
  98.         a(g(7)),        # second
  99.         0,
  100.         0,
  101.         0
  102.         )
  103.  
  104. # parsdate.parsedate    - ~700/sec.
  105. # parse_http_date       - ~1333/sec.
  106.  
  107. weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  108. monthname = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
  109.              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
  110.  
  111. def build_http_date (when):
  112.     year, month, day, hh, mm, ss, wd, y, z = time.gmtime(when)
  113.     return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
  114.             weekdayname[wd],
  115.             day, monthname[month], year,
  116.             hh, mm, ss)
  117.  
  118. def parse_http_date (d):
  119.     d = string.lower (d)
  120.     tz = time.timezone
  121.     if rfc850_reg.match (d) == len(d):
  122.         retval = int (time.mktime (unpack_rfc850()) - tz)
  123.     elif rfc822_reg.match (d) == len(d):
  124.         retval = int (time.mktime (unpack_rfc822()) - tz)
  125.     else:
  126.         return 0
  127.     # Thanks to Craig Silverstein <csilvers@google.com> for pointing
  128.     # out the DST discrepancy
  129.     if time.daylight and time.localtime(retval)[-1] == 1: # DST correction
  130.         retval = retval + (tz - time.altzone)
  131.     return retval
  132.